20180510 AMG專輯篩選練習

前面的部分和前節的代碼相同,
這次要做的只是完善換頁時的重複賦值部份而已。

首先一樣,先導入模組、建立label字典,以及給定post需要用到的headers和data。

from seleniumrequests import Chrome 
import requests
import re
from bs4 import BeautifulSoup

chrome_path = r"C:\Users\Ramone\seleniumdriver\chrome\chromedriver.exe" # 給定一個瀏覽器的local位置
webdriver = Chrome(chrome_path) # 導入Chorme當作webdriver

#建立Label字典
label_res= webdriver.request('GET','https://www.allmusic.com/advanced-search/') 
label_soup = BeautifulSoup(label_res.text,"lxml")
label = label_soup.find_all('input',{'id':re.compile('genreid.*?')})
label_dict={}
for l in label:
    label_dict[l['value']]=l['id']

#建立評價字典
rating_dict={}
star=1.0
for i in range(1,10):
    rating_dict[str(star)]='editorialrating:'+str(i)
    star+=0.5

#headers直接從network複製
amg_header={
'accept': r'text/html, */*; q=0.01',
'accept-encoding': r'gzip, deflate, br',
'accept-language': r'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6',
'content-length': '39',
'content-type': r'application/x-www-form-urlencoded; charset=UTF-8',
'cookie': r'_ga=GA1.2.85029673.1513518205; __gads=ID=3275e8321c618a22:T=1513518176:S=ALNI_MbT7eOHrtfYxgOBlXi-4NZzwkA01Q; __qca=P0-704611526-1513518207321; policy=notified; registration_prompt=true; _gid=GA1.2.939754473.1525263314; bm_monthly_unique=true; allmusic_session=a%3A6%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22498c8bf394d58ea40993a276a34e6bfc%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A11%3A%2210.128.8.22%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A115%3A%22Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F65.0.3325.181+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1525278399%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A4%3A%22user%22%3Bi%3A0%3B%7Dedeeacbf1b0d945d29d143bc59a40129; _gat=1; _gat_cToolbarTracker=1; bm_last_load_status=BLOCKING; bm_daily_unique=true; bm_sample_frequency=100',
'origin': r'https://www.allmusic.com',
'referer': r'https://www.allmusic.com/advanced-search',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
'x-requested-with': 'XMLHttpRequest',
}

#formdata
label_input= input("請輸入音樂類別 (Geners & Styles) ex:Country-Folk : ")
while label_input not in label_dict:
    label_input= input("類別不存在,請確認後重新輸入,或輸入""label_dict""查詢所有類別: ")
    if label_input == 'label_dict':
        for k in label_dict:
            print (k)
rating_input = input("請輸入評價幾顆星 (All Music Raing) ex:5.0 :")
while rating_input not in rating_dict:
    rating_input= input("請輸入評價幾顆星 1.0/ 1.5/ 2.0/ 2.5/ 3.0/ 3.5/ 4.0/ 4.5/ 5.0: ")

#替input的資訊給一個value_name
amg_label=label_dict[label_input] 
amg_rating=rating_dict[rating_input]

再來處理換頁的部分,
用開發人員工具(network)去檢查換頁的規則,發現其實很容易,
只會有url的尾碼數字不同,headers和data都沒有變化,
我們用bs和正則表達把變化的url挑出來。
接著將完整的url網址(amg_url+next_url),餵給next_res這個value。

#將headers,data包給selenium-request做post請求
webdriver = Chrome(chrome_path)
res= webdriver.request('POST','https://www.allmusic.com/advanced-search/results/'
                       ,headers=amg_header,data="filters[]=%s&filters[]=%s" %(amg_label,amg_rating))
res_soup = BeautifulSoup(res.text,'lxml')

#用開發人員工具,找到換頁的模式的規則產生下一次的respond
next_page = res_soup.find_all('span',{'class':'next'})
amg_url = 'https://www.allmusic.com/'
next_url=re.compile(r'(?=/advanced-search/results/)/advanced-search/results/\d+')
next_res = amg_url+re.search(next_url,str(next_page[-1])).group()

因為程度不好,後面在輸出資料的代碼邏輯寫得很冗長,
這邊我先定義一些functino以便之後重複使用,
(這部分因為觀念不好,花了很多時間。)

#建立一個BS抓取原始碼的function並用class包裝起來,便於之後取用。 (用字典的形式也可以)
class get_info():
    def __init__(self,artist,title,year):
        self.artist=artist
        self.title=title
        self.year=year
def get_source():
    artist = res_soup.find_all('td',{'class':'artist'})
    title = res_soup.find_all('td',{'class':'title'})
    year = res_soup.find_all('td',{'class':'year'})
    return get_info(artist,title,year)
#   return {'artist':artist,'title':title,'year':year} (用字典的形式也可以)

#建立濾除換行符號並加入list的function,這部分是方便到之後做迴圈輸出需要。
def add_list(y):
    y_list=[]
    for x in y:
        x_text=x.text
        x_str=x_text.strip()
        y_list.append(x_str)
    return y_list

最後就是輸出我們需要的資料了,
next_page為bs剖析完的list,(bs剖析有找到下一頁的時候,不為空的list)
我們以next_page當作判別式,
將輸出的部分,只有一頁時,或是多頁時來編碼,如下:

#只有一頁的時候就做這個,把當頁的資料做bs剖析並做迴圈打印list。 
print ('>>>page<<<' )
i=0
while i <len(add_list(get_source().title)):
    print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
    i=i+1

#有很多頁的話就做這個
while next_page != []:
    #把下一頁的url丟到post重新做打印
    res= webdriver.request('POST',next_res,headers=amg_header,data="filters[]=%s&filters[]=%s" %(amg_label,amg_rating))
    res_soup = BeautifulSoup(res.text,'lxml')
    print ('>>>page<<<' )
    i=0 
    while i <len(add_list(get_source().title)):
        print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
        i=i+1
    #當下一頁的post結果又有找到下一頁時,將next_res重新賦值,持續到 next_page為空
    next_page = res_soup.find_all('span',{'class':'next'}) 
    if next_page != []:
        next_res = amg_url+re.search(next_url,str(next_page[-1])).group()
#只有一頁的時候就做這個
if next_page == []:
    print ('>>>page<<<' )
    i=0
    while i <len(add_list(get_source().title)):
        print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
        i=i+1
#有很多頁的時候就做這個
else:
    #先把下一頁的網址包起來
    next_res = amg_url+re.search(next_url,str(next_page[-1])).group()
    #還有下一頁之後就持續打印
    while next_page != []:
        print ('>>>page<<<' )
        i=0 
        while i <len(add_list(get_source().title)):
            print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
            i=i+1
        #並把下一頁的原始碼餵到下一次爬蟲   
        res= webdriver.request('POST',next_res,headers=amg_header,data="filters[]=%s&filters[]=%s" %(amg_label,amg_rating))
        res_soup = BeautifulSoup(res.text,'lxml')
        next_page = res_soup.find_all('span',{'class':'next'})
        #如果還有下一頁就再更新一次下一頁的網址,如果沒有就把最後一頁印出來
        if next_page != []:
            next_res = amg_url+re.search(next_url,str(next_page[-1])).group()
        else:
            print ('>>>page<<<' )   
            i=0 
            while i <len(add_list(get_source().title)):
                print (add_list(get_source().artist)[i],"-",add_list(get_source().title)[i],"-",add_list(get_source().year)[i])
                i=i+1

大功告成,
此次練習是從"音樂類別"和"評價"去做Post,
但實際上聽音樂時我們怎麼會知道這種類型的音樂分類是什麼呢,
所以這樣開頭的體驗其實不是很人性化,
如果我們可以從某樂團、或專輯開始,也許是一個更好的主意。
(也許可以從google做判別導向,再把資料轉換過後丟給AMG或其他有公信力的網站做爬蟲)

Source credit: All Music : https://www.allmusic.com/
No copyright infringement intended.

results matching ""

    No results matching ""